<?php
/**
 * Description of Helper_UploadFile
 *
 * Clase que nos ayuda a subir un archivo en una direccion indicada
 *
 * @author H4845
 */
class Helper_UploadFile
{
    const TYPE_IMAGES = 1;
    const TYPE_DESIGNS = 2;
    const TYPE_DOCS = 3;

    const SIZE_1KB = 1024;
    const SIZE_1MB = 1148576;
    const SIZE_3MB = 3148576;
    const SIZE_5MB = 5342880;

    const UPLOAD_OK = 0;
    const ERROR_NO_UPLOAD = 1;
    const ERROR_UNSOPORTED_FILE = 2;
    const ERROR_NO_SIZE = 3;
    const ERROR_UNKNOWN = 4;

    private $_types = null;
    private $_mimeTypes = null; // areglo de mimetypes para las extenciones
    private $_extentions = null;
    private $_maxSize = 0;
    private $_defaultFolder = ''; // direccion por default a donde se subira

    public function __construct($types = array(self::TYPE_IMAGES), 
                                $maxSize = self::SIZE_1MB,
                                $defaultFolder = 'uploads/register_files')
    {
        $this->_types = array();
        $this->_extentions = array();
        $this->_mimeTypes = array();

        $this->changeMaxSize($maxSize);
        $this->changeSaveFolder($defaultFolder);
        $this->addTypesForUpload($types);
    }

    public function changeSaveFolder($folder)
    {
        $this->_defaultFolder = $folder;
    }

    public function changeMaxSize($maxSize)
    {
        $this->_maxSize = $maxSize;
    }

    public function addTypesForUpload($types)
    {
        foreach($types as $type)
        {
            if(!in_array($type, $this->_types))
            {
                $this->_types[] = $type;

                switch($type)
                {
                    case self::TYPE_IMAGES:
                        $this->_extentions[] = 'jpeg';
                        $this->_extentions[] = 'jpg';
                        $this->_extentions[] = 'bmp';
                        $this->_extentions[] = 'gif';

                        $this->_mimeTypes[] = 'image/jpeg';
                        $this->_mimeTypes[] = 'image/jpg';
                        $this->_mimeTypes[] = 'image/pjpeg';
                        $this->_mimeTypes[] = 'image/bmp';
                        $this->_mimeTypes[] = 'image/gif';
                        break;
                    case self::TYPE_DESIGNS:
                        $this->_extentions[] = 'png';
                        $this->_extentions[] = 'psd';

                        $this->_mimeTypes[] = 'image/png';
                        $this->_mimeTypes[] = 'image/x-png';
                        $this->_mimeTypes[] = 'image/png';
                        $this->_mimeTypes[] = 'image/vnd.adobe.photoshop';
                        $this->_mimeTypes[] = 'application/octet-stream';
                        break;
                    case self::TYPE_DOCS:
                        $this->_extentions[] = 'pdf';

                        $this->_mimeTypes[] = 'application/pdf';
                        break;
                }
            }
        }
    }

    /**
     * Metodo que valida si existe error en un archivo dependiendo de las condiciones configuradas a la clase.
     *  regresa falso si tiene ningun error, y numerico si existe erro indicando el codigo de error
     * @param  $file
     * @return boolean
     */
    private function existErrorFile($file)
    {
        $ret = self::ERROR_UNKNOWN;

        // primer filtro por extencion de archivo
        $parts = explode('.', $file['name']);
        $extension = strtolower($parts[count($parts) - 1]);

        // filtro de tipos MIME y tamaños
        
        if( count($parts) > 1 && in_array($extension,$this->_extentions) &&
            in_array($file['type'], $this->_mimeTypes)
           )
        {
            if($file['size'] >= self::SIZE_1KB && $file['size'] <= $this->_maxSize)
            {
                $componentes = explode('/', $file['type']);
                $ret = true;

                // validaciones para cuando es imagen con respecto al mime tipe
                if($componentes[0] == 'image')
                {
                    // referencias: http://foro.elhacker.net/nivel_web/php_upload_security-t277601.0.html
                    // verificacion por exif_imagetype()   -> requiere habilitar modulo en php
                    $imaginf = getimagesize($file['tmp_name']);

                    if( !in_array($imaginf['mime'], $this->_mimeTypes) )
                    {
                        $ret = self::ERROR_UNSOPORTED_FILE;
                    }
                }    
                $ret = false;
            }
            else
            {
                $ret = self::ERROR_NO_SIZE;
            }
        }
        else
        {
            $ret = self::ERROR_UNSOPORTED_FILE;
        }
        return $ret;
    }

    /**
     * Metodo que sube un solo archivo
     * @param array('name','type','tmp_name','error','size') $fileInfo
     * @param string $newName  es el nombre con el que se guardara el archivo (sin extension)
     * @return array('result','errorCode', 'path')
     */

    public function uploadIndividualFile($fileInfo, $newName)
    {
        $helperSubirArchivos = new Helper_SubirArchivos();
        $ret = array('result' => false, // resultado del subir la imagen
                     'errorCode' => self::ERROR_UNKNOWN, // codigo de error
                     'path' => ''); // direccion en la que se guardo

        $ret['errorCode'] = $this->existErrorFile($fileInfo);

        if($ret['errorCode'] == false) //  no hay error
        {
            $parts = explode('.', $fileInfo['name']);
            $nameArchivo = $newName;
            $extension = strtolower($parts[count($parts) - 1]);
            $nameArchivo.= '.' . $extension;

            $uploadImage = $helperSubirArchivos->subirArchivos($fileInfo, $this->_defaultFolder, null, $nameArchivo);
            if($uploadImage)
            {
                $ret['result'] = true;
                $ret['errorCode'] = self::UPLOAD_OK; // code 1
                $ret['path'] = $this->_defaultFolder . '/' . $nameArchivo;
            }
            else
            {
                $ret['result'] = false;
                $ret['errorCode'] = self::ERROR_NO_UPLOAD; // code 2
            }
        }

        return $ret;
    }

    public function getUploadMessage($errorCode)
    {
        $msj='';
        switch($errorCode)
        {
            case self::UPLOAD_OK: 
                $msj = 'Archivo cargada exitosamente...';
                break;
            case self::ERROR_NO_UPLOAD:
                $msj = 'El archivo no se pudo subir, int&eacute;ntelo nuevamente.';
                break;
            case self::ERROR_UNSOPORTED_FILE:
                $supportedFiles = implode(',', $this->_extentions);
                $msj = 'Tipo de archivo invalido, se aceptan:'.$supportedFiles;
                break;
            case self::ERROR_NO_SIZE:

                $base = log($this->_maxSize) / log(self::SIZE_1KB);
                $suffix = array('', 'kb', 'Mb', 'Gb', 'Tb');
                $formatSize =  round(pow(self::SIZE_1KB, $base - floor($base)), 2) . $suffix[floor($base)];

                $msj = 'El archivo supero el tamaño m&aacute;ximo permitido('.$formatSize.')';
                break;
            default:
                $msj = 'Error inesperado.';
                break;
        }


        return $msj;
    }

}
